import type { MenuProps } from 'antd';
import GlobalContext from '/@/Layouts/GlobalContext';
import { Menu, Layout } from 'antd';
const { Sider } = Layout;
import React, { useEffect, useContext, useMemo } from 'react';
import { OpenedMenu } from '/@/types/menu';
import { useStateThemeConfig } from '/@/store/hooks/theme';
import { useDispatchMenu, useStateMenuList, useStateOpenMenuKey, useStateselectMenuKey } from '/@/store/hooks/menu';
import { useLocation, useNavigate, useParams } from 'react-router';
import Icon from '/@/components/icon';
import Logo from '../navBar/Logo';
import { t } from 'i18next';
import _ from 'lodash';
import { useAliveController } from 'react-activation';
import { useAuth } from '/@/components/AuthContext';
interface MenuItemsArr {
  ismu: boolean;
  path: string;
  element?: any;
  LayoutHide?: boolean;
  roles?: string[];
  access?: string;
  icon?: any;
  name?: string;
  redirect?: string;
  children?: MenuItemsArr[];
  isAuthMenu: boolean;
}
type MenuItem = Required<MenuProps>['items'][number];
function getItem(label: React.ReactNode, key: React.Key, icon?: React.ReactNode, children?: MenuItem[]): MenuItem {
  return {
    key,
    icon,
    children,
    label,
  } as MenuItem;
}

//生成MenuItem
const MenuItems = (arr: MenuItemsArr[]): any[] => {
  let router: MenuItem[] = [];
  //过滤数组并遍历生成MenuItem
  arr.map((item) => {
    if (item.children === undefined || item.children.length === 0) {
      router.push(getItem(t(item.name as string), item.path, item.icon && <Icon icon={item.icon} />));
    } else if (item.children.length > 0) {
      router.push(
        getItem(
          t(item.name as string),
          item.path,
          item.icon && <Icon icon={item.icon} />,
          MenuItems(item.children) as MenuItem[]
        )
      );
    }
  });
  return router;
};

const Menus: React.FC = () => {
  const { clear } = useAliveController();
  const { stateAddOpenedMenu } = useDispatchMenu();
  const { menuBarWidth, IsLogo, topBarHight, layout, language } = useStateThemeConfig();
  //获取路由信息
  const location = useLocation();
  //权限标识
  let role = useAuth().auth;
  //过滤路由
  const FilterRoute = (arr: MenuItemsArr[]): MenuItemsArr[] => {
    return arr.filter((v) => {
      v['ismu'] = true;
      if (v.children) {
        v.children = FilterRoute(v.children);
      }
      //权限控制
      v.roles &&
        v.roles.forEach(() => {
          if (v.roles && v.roles.includes(role)) {
            v['ismu'] = true;
          } else {
            v.isAuthMenu = v?.isAuthMenu ?? true;
            if (v.isAuthMenu) {
              v['ismu'] = true;
            } else {
              v['ismu'] = false;
            }
          }
        });
      return !v?.LayoutHide && v?.ismu;
    });
  };
  const params = useParams();
  //当前路由路径
  const currentPath = useMemo(() => {
    const { pathname } = location;
    return pathname;
  }, [location]);
  //路由跳转
  const navigate = useNavigate();
  //获取redux路由中的菜单
  const routerList = useStateMenuList();
  const menusDeep = _.cloneDeep(routerList);
  //提交dispath中的hooks方法
  const { stateSetOpenMenuKey: onOpenChange, stateSetselectMenuKey, stateSetCurrentPath } = useDispatchMenu();
  //菜单items
  const Items = useMemo(() => MenuItems(FilterRoute(menusDeep))[0].children, [routerList, language]);

  //获取redux中当前菜单展开项
  const openKeys = useStateOpenMenuKey();
  //获取redux中当前选中项
  const selectedKeys = useStateselectMenuKey();
  //处理详情高亮问题
  const setParentHighlight = () => {
    //此函数用来转换动态路由
    function convertId(str: string, obj: any) {
      let newStr = str;
      Object.keys(obj).forEach((key) => {
        const regExp = new RegExp(`\\/(${obj[key]})`, 'g');
        newStr = newStr.replace(regExp, `/:${key}`);
      });
      return newStr;
    }
    const pathSplit = convertId(currentPath, params).split('/');
    if (pathSplit.includes('details')) {
      return currentPath.substring(0, currentPath.lastIndexOf('/details'));
    }
    if (params) {
      return convertId(currentPath, params);
    }
    return selectedKeys;
  };
  //处理打开项数据
  const handleOpenData = (result: MenuItemsArr[], path: string) => {
    function loop(list: MenuItemsArr[], keys = []) {
      for (let item of list) {
        let newItempath = item.path
          .split('/')
          .map((vv: any) => {
            if (vv[0] === ':') {
              vv = params[vv.substring(1)];
            }
            return vv;
          })
          .join('/');
        if (newItempath === path) {
          // 如果路由path与item.router相等则直接返回当前路由的所有上级的router
          return [...keys];
        } else if (item.children && item.children.length) {
          let tempResult: any = loop(item.children, [...keys, newItempath] as any);
          if (tempResult !== false) {
            return tempResult;
          }
        }
      }
      return false;
    }

    stateSetCurrentPath(currentPath);
    onOpenChange(loop(result));
  };
  //菜单收缩
  const { collapsed } = useContext(GlobalContext);
  const addTegsView = () => {
    let result: any = [];
    //铺平数组
    const findInfo = (arr: any) => {
      arr.forEach((item: MenuItem) => {
        const { children, ...info } = item as any;
        result.push(info);
        if (children) {
          findInfo(children); // 递归处理子节点
        }
      });
    };
    findInfo(routerList);
    //设置了isAffix固定的直接添加tagsview
    result
      .filter((item: any) => item.isAffix === true)
      .forEach((v: any) => {
        stateAddOpenedMenu({ path: v.path, title: v.name || 'menu.notitle', isAffix: v.isAffix, icon: v.icon });
      });
    let penedMenu: OpenedMenu = {
      path: '/',
      isAffix: true,
      title: 'menu.home',
    };
    result.filter((item: any) => {
      let newItempath = item.path
        .split('/')
        .map((vv: any) => {
          if (vv[0] === ':') {
            vv = params[vv.substring(1)];
          }
          return vv;
        })
        .join('/');
      if (item.isAffixdd !== false) {
        return newItempath === currentPath
          ? (penedMenu = {
              path: newItempath,
              title: item.name || 'menu.notitle',
              isAffix: item.isAffix,
              icon: item.icon,
            })
          : null;
      }
    }) as any;
    stateAddOpenedMenu(penedMenu);
  };
  useEffect(() => {
    stateSetselectMenuKey([currentPath]);
    handleOpenData(routerList, currentPath);
    addTegsView();
  }, [currentPath, collapsed]);
  //菜单选中时回调
  const onSelect = ({ key }: any) => {
    clear();
    navigate(key);
  };

  return (
    <>
      {layout !== 'transverse' ? (
        <Sider
          width={menuBarWidth}
          style={{
            height: '100%',
            position: 'sticky',
            left: 0,
            top: layout === 'circular' ? topBarHight + 'px' : 0,
            background: 'var(--squidwest-color-menuBar)',
          }}
          trigger={null}
          collapsible
          collapsed={collapsed}
        >
          {IsLogo && layout === 'default' && !collapsed && <Logo></Logo>}
          <Menu
            openKeys={openKeys}
            selectedKeys={setParentHighlight()}
            onOpenChange={onOpenChange as any}
            mode='inline'
            theme='dark'
            items={Items}
            onSelect={onSelect}
          />
        </Sider>
      ) : (
        <Menu
          selectedKeys={setParentHighlight()}
          mode='horizontal'
          className='inline-menu'
          items={Items}
          onSelect={onSelect}
        />
      )}
    </>
  );
};

export default Menus;
